#include "roi.h"

static Mat QImageTocvMat(const QImage& image)
{
    Mat mat;
    switch (image.format())
    {
    case QImage::Format_Grayscale8:
    case QImage::Format_Indexed8:
        mat = Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
        break;
    case QImage::Format_ARGB32:
    case QImage::Format_RGB32:
    case QImage::Format_A2RGB30_Premultiplied:
        mat = Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
        cvtColor(mat, mat, COLOR_BGRA2BGR);
        break;
    case QImage::Format_RGB888:  // RR GG BB 字节存储
        mat = Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
        cvtColor(mat, mat, COLOR_RGB2BGR);
        break;
    }
    return mat;
}

ROI::ROI(QGraphicsItem *parent)
    :QGraphicsItem(parent),
    m_rect(QRectF(0, 0, 200, 100)),
    m_pos(QPoint(0,0)),
    m_isResizing(false),
    m_isMoving(false),
    m_isRotating(false),
    m_isSelected(false)
{
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5,5), m_rect.size()-QSize(10,10));
    setFlag(ItemSendsGeometryChanges);      //  自定义控件变换信号
    setAcceptHoverEvents(true);             //  接受鼠标停留信号，默认是关闭的
    setCursor(Qt::OpenHandCursor);          //  设置鼠标模式
}

QRectF ROI::boundingRect() const
{
    return m_rect;
}

void ROI::setMask(const QList<QGraphicsItem *> &items, Mat &mask)
{
    Mat tmp, src;
    for(auto Gitem : items)
    {
        if(Gitem->type() == QGraphicsPixmapItem::Type)
        {
            QGraphicsPixmapItem *pixmap = dynamic_cast<QGraphicsPixmapItem*>(Gitem);
            src = QImageTocvMat(pixmap->pixmap().toImage());
            tmp = Mat::zeros(src.rows, src.cols, CV_8UC1);
            break;
        }
    }

    for(auto Gitem : items)
    {
        if(Gitem->type() == QGraphicsPixmapItem::Type)
            continue;

        ROI* item = dynamic_cast<ROI*>(Gitem);
        if(item == nullptr)
            continue;

        QPainterPath path;
        QTransform transform;

        switch (item->m_shape)
        {
        case ROIShape::RECTANGE:
            path.addRect(item->getBoundingRect());
            break;
        case ROIShape::ROTATERECTANGE:
        {
            path.addRect(item->getBoundingRect());
            RotateRectangle *rect = dynamic_cast<RotateRectangle*>(item);
            if(rect)
                transform = rect->getQTransform();
            else
                qDebug() << "rect is nullptr";
            path = transform.map(path);
        }
        break;
        case ROIShape::ELLIPSE:
        case ROIShape::CIRCLE:
            path.addEllipse(item->getBoundingRect());
            break;
        case ROIShape::POLYGON:
            QPolygonF polygon;
            item->getPolygon(polygon);
            path.addPolygon(polygon);
            break;
        }
        path = path.simplified();
        vector<vector<cv::Point>> contours;
        contours.push_back({});
        for (int i = 0; i < path.elementCount(); ++i)
        {
            QPointF point = path.elementAt(i);
            contours[0].push_back(cv::Point(point.x(), point.y()));
        }
        if(contours[0].size() == 0)
            continue;
        cv::drawContours(tmp, contours, 0, Scalar(255), FILLED);
    }
    if(items.size() <= 1)
        mask = Mat::ones(src.rows, src.cols, CV_8UC1)*255;
    else
        mask = tmp.clone();
}

QRectF ROI::getBoundingRect()
{
    return m_SRect;
}

void ROI::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *del = new QAction("删除", this);
    menu.addAction(del);

    // 删除
    connect(del, &QAction::triggered, this, [=]{
        scene()->removeItem(this);
        emit upROIMask();
    });

    menu.exec(event->screenPos());      // 鼠标点击的地方显示菜单
}

void ROI::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    m_isSelected = true;
    QGraphicsItem::hoverEnterEvent(event);
}

void ROI::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
{
    m_isSelected = false;
    QGraphicsItem::hoverLeaveEvent(event);
}

// ------------------  Rectangle  ----------------------
Rectangle::Rectangle()
{
    m_shape = ROIShape::RECTANGE;
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5, 20), m_rect.size()-QSize(10, 25));
}

Rectangle::Rectangle(QRectF &rectf)
{
    m_shape = ROIShape::RECTANGE;
    m_rect = rectf;
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5, 20), m_rect.size()-QSize(10, 25));
}

void Rectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    if(scene() == nullptr)
        return ;
    scene()->update();

    QPen pen(Qt::red);
    pen.setStyle(Qt::DashLine);
    painter->setPen(pen);
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5, 20), m_rect.size()-QSize(10, 25));

    painter->drawRect(getBoundingRect());  // 画矩形

    if(m_isSelected)
    {
        m_scaleRect1 = QRectF(m_SRect.topLeft()-QPointF(5,5), QSize(10,10));
        m_scaleRect2 = QRectF(QPointF(m_SRect.center().x()-5, m_SRect.top()-5), QSize(10,10));
        m_scaleRect3 = QRectF(m_SRect.topRight()-QPointF(5,5), QSize(10,10));
        m_scaleRect4 = QRectF(QPointF(m_SRect.left()-5, m_SRect.center().y()-5), QSize(10,10));
        m_scaleRect5 = QRectF(QPointF(m_SRect.right()-5, m_SRect.center().y()-5), QSize(10,10));
        m_scaleRect6 = QRectF(m_SRect.bottomLeft()-QPointF(5,5), QSize(10,10));
        m_scaleRect7 = QRectF(QPointF(m_SRect.center().x()-5, m_SRect.bottom()-5), QSize(10,10));
        m_scaleRect8 = QRectF(m_SRect.bottomRight()-QPointF(5,5), QSize(10,10));

        painter->setBrush(Qt::green);
        painter->drawRect(m_scaleRect1);
        painter->drawRect(m_scaleRect2);
        painter->drawRect(m_scaleRect3);
        painter->drawRect(m_scaleRect4);
        painter->drawRect(m_scaleRect5);
        painter->drawRect(m_scaleRect6);
        painter->drawRect(m_scaleRect7);
        painter->drawRect(m_scaleRect8);
    }
}

void Rectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        // qDebug() << "press";
        QPointF pos = event->pos();
        m_pos = pos;

        // 检查8个功能点
        if(m_scaleRect1.contains(pos))
        {
            m_s1 = true;
            setCursor(Qt::SizeFDiagCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect2.contains(pos))
        {
            m_s2 = true;
            setCursor(Qt::SizeVerCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect3.contains(pos))
        {
            m_s3 = true;
            setCursor(Qt::SizeBDiagCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect4.contains(pos))
        {
            m_s4 = true;
            setCursor(Qt::SizeHorCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect5.contains(pos))
        {
            m_s5 = true;
            setCursor(Qt::SizeHorCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect6.contains(pos))
        {
            m_s6 = true;
            setCursor(Qt::SizeBDiagCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect7.contains(pos))
        {
            m_s7 = true;
            setCursor(Qt::SizeVerCursor);
            event->accept();
            return ;
        }
        else if(m_scaleRect8.contains(pos))
        {
            m_s8 = true;
            setCursor(Qt::SizeFDiagCursor);
            event->accept();
            return ;
        }
        m_isMoving = true;
    }
}

void Rectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF newPos = event->pos();
    // 计算移动的距离
    qreal dx = event->pos().x() - m_pos.x();
    qreal dy = event->pos().y() - m_pos.y();

    QRectF tmp = m_rect;
    QRectF last = tmp;
    bool flag = true;

    if(m_isMoving)
    {
        // qDebug() <<"move";
        tmp.setRect(tmp.x()+dx, tmp.y()+dy, tmp.width(), tmp.height());
        QGraphicsItem::mouseMoveEvent(event);
    }
    else if(m_s2)
    {
        tmp.setRect(tmp.x(), tmp.y()+dy, tmp.width(), tmp.height()-dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }
    else if(m_s3)
    {
        tmp.setRect(tmp.x(), tmp.y()+dy, tmp.width()+dx, tmp.height()-dy);
        setCursor(Qt::SizeBDiagCursor);
        event->accept();
    }
    else if(m_s4)
    {
        tmp.setRect(tmp.x()+dx, tmp.y(), tmp.width()-dx, tmp.height());
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_s5)
    {
        tmp.setRect(tmp.x(), tmp.y(), tmp.width()+dx, tmp.height());
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_s6)
    {
        tmp.setRect(tmp.x()+dx, tmp.y(), tmp.width()-dx, tmp.height()+dy);
        setCursor(Qt::SizeBDiagCursor);
        event->accept();
    }
    else if(m_s7)
    {
        tmp.setRect(tmp.x(), tmp.y(), tmp.width(), tmp.height()+dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }
    else if(m_s8)
    {
        tmp.setRect(tmp.x(), tmp.y(), tmp.width()+dx, tmp.height()+dy);
        setCursor(Qt::SizeFDiagCursor);
        event->accept();
    }
    else if(m_s1)
    {
        tmp.setRect(tmp.x()+dx, tmp.y()+dy, tmp.width()-dx, tmp.height()-dy);
        setCursor(Qt::SizeFDiagCursor);
        event->accept();
    }
    prepareGeometryChange();
    // scene()->update(boundingRect());

    // 小于某个值就退出
    if(tmp.width() <= 30)
    {
        m_rect = last;
        flag = false;
    }
    if(tmp.height() <= 45)
    {
        m_rect = last;
        flag = false;
    }
    if(flag)
    {
        m_pos = newPos;
        m_rect = tmp;
        m_SRect = QRectF(m_rect.topLeft() + QPointF(5, 20), m_rect.size()-QSize(10, 25));
    }
}

void Rectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        if(m_isMoving || m_s1 || m_s2 || m_s3 || m_s4 || m_s5 || m_s6 || m_s7 || m_s8 )
        {
            m_isMoving = m_s1 = m_s2 = m_s3 = m_s4 = m_s5 = m_s6 = m_s7 = m_s8 = false;
            setCursor(Qt::OpenHandCursor);
            event->accept();
            emit upROIMask();
            return;
        }
    }
}

void Rectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QPointF pos = event->pos();
    m_pos = pos;
    if(m_scaleRect1.contains(pos) || m_scaleRect8.contains(pos))
    {
        setCursor(Qt::SizeFDiagCursor);
        event->accept();
        return ;
    }
    else if(m_scaleRect2.contains(pos) || m_scaleRect7.contains(pos))
    {
        setCursor(Qt::SizeVerCursor);
        event->accept();
        return ;
    }
    else if(m_scaleRect3.contains(pos) || m_scaleRect6.contains(pos))
    {
        setCursor(Qt::SizeBDiagCursor);
        event->accept();
        return ;
    }
    else if(m_scaleRect4.contains(pos) || m_scaleRect5.contains(pos))
    {
        setCursor(Qt::SizeHorCursor);
        event->accept();
        return ;
    }
    setCursor(Qt::OpenHandCursor);
}

void Rectangle::setboundingRect(QRectF &rectf)
{
    m_rect = rectf;
}

// ------------------  RotateRectangle  ----------------------
RotateRectangle::RotateRectangle()
{
    m_shape = ROIShape::ROTATERECTANGE;
}

RotateRectangle::RotateRectangle(QRectF &rectf)
{
    m_shape = ROIShape::ROTATERECTANGE;
    m_rect = rectf;
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5, 20), m_rect.size()-QSize(10, 25));
}

void RotateRectangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Rectangle::paint(painter, option, widget);
    // 画旋转点
    if(m_isSelected)
    {
        QRectF m_rotateRect = QRectF(QPointF(m_rect.center().x()-5, m_rect.top()),QSize(10,10));
        painter->setBrush(Qt::cyan);
        painter->drawRect(m_rotateRect);
    }
    setTransform(m_transform);
}

void RotateRectangle::setboundingRect(QRectF &rectf, QTransform& transform)
{
    m_rect = rectf;
    m_transform = transform;
}

void RotateRectangle::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        QPointF pos = event->pos();
        m_pos = pos;

        // 检查 上中间的功能点
        QRectF m_rotateRect = QRectF(QPointF(m_rect.center().x()-5, m_rect.top()), QSize(10,10));
        if(m_rotateRect.contains(pos))
        {
            m_initRotation = rotation();
            m_isRotating = true;
            setCursor(Qt::PointingHandCursor);
            event->accept();
            return ;
        }
        Rectangle::mousePressEvent(event);
    }
}

void RotateRectangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF newPos = event->pos();
    qreal dx = newPos.x()-m_pos.x();
    qreal dy = newPos.y()-m_pos.y();

    if(m_isRotating)
    {
        QPointF localPos = event->pos();
        QVector2D startVec(m_pos.x() - m_rect.center().x(), m_pos.y()-m_rect.center().y());
        startVec.normalize();
        QVector2D endVec(localPos.x() - m_rect.center().x(), localPos.y()-m_rect.center().y());
        endVec.normalize();

        qreal dotValue = QVector2D::dotProduct(startVec, endVec);

        if(dotValue > 1.0)
            dotValue = 1.0;
        else if(dotValue < -1.0)
            dotValue = -1.0;

        dotValue = qAcos(dotValue);
        if(isnan(dotValue))
            dotValue = 0.0;

        // 获取角度
        qreal angle = dotValue * 1.0/(PI/180);
        // 向量叉乘获取方向
        QVector3D crossValue = QVector3D::crossProduct(QVector3D(startVec, 1.0), QVector3D(endVec, 1.0));
        if(crossValue.z() < 0)
            angle = -angle;
        m_initRotation += angle;

        // 设置变换矩阵
        m_transform.translate(m_rect.center().x(), m_rect.center().y());  // 将矩阵平移到场景的坐标原点进行旋转
        m_transform.rotate(m_initRotation);
        m_transform.translate(-m_rect.center().x(), -m_rect.center().y());// 旋转结束将矩阵平移回去

        setTransform(m_transform);

        setCursor(Qt::PointingHandCursor);
        event->accept();
    }
    Rectangle::mouseMoveEvent(event);
}

void RotateRectangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        if(m_isRotating)
        {
            m_isRotating = false;
            setCursor(Qt::OpenHandCursor);
            emit upROIMask();
            event->accept();
        }
        Rectangle::mouseReleaseEvent(event);
    }
}

void RotateRectangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QPointF pos = event->pos();
    m_pos = pos;
    QRectF m_rotateRect = QRectF(QPointF(m_rect.center().x()-5, m_rect.top()), QSize(10,10));
    if(m_rotateRect.contains(pos))
    {
        setCursor(Qt::PointingHandCursor);
        return;
    }
    else
    {
        setCursor(Qt::OpenHandCursor);
    }
    Rectangle::hoverMoveEvent(event);
}

QTransform &RotateRectangle::getQTransform()
{
    return m_transform;
}


// ------------------  Ellipse  ----------------------
Ellipse::Ellipse()
{
    m_shape = ROIShape::ELLIPSE;
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5,5), m_rect.size()-QSize(10,10));
}

Ellipse::Ellipse(QRectF &rectf)
{
    m_shape = ROIShape::ELLIPSE;
    m_rect = rectf;
    m_SRect = QRectF(m_rect.topLeft() + QPointF(5,5), m_rect.size()-QSize(10,10));
}

void Ellipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);
    if(scene() == nullptr)
        return;
    scene()->update();

    QPen pen(Qt::red);
    pen.setStyle(Qt::DashLine);
    painter->setPen(pen);

    // 画椭圆
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5,5), m_rect.size()-QSize(10,10));
    painter->drawEllipse(getBoundingRect());
    // painter->drawEllipse(m_rect);
    // 画功能点
    if(m_isSelected)
    {
        m_pointUp = QRectF(QPointF(m_rect.center().x()-5, m_rect.top()), QSize(10,10));
        m_pointDown = QRectF(QPointF(m_rect.center().x()-5, m_rect.bottom()-10), QSize(10,10));
        m_pointLeft = QRectF(QPointF(m_rect.left(), m_rect.center().y()-5), QSize(10,10));
        m_pointRight = QRectF(QPointF(m_rect.right()-10, m_rect.center().y()-5), QSize(10,10));
        painter->setBrush(Qt::green);
        painter->drawRects(QList<QRectF>{m_pointUp, m_pointDown, m_pointLeft, m_pointRight});
    }
}

void Ellipse::setboundingRect(QRectF &rectf)
{
    m_rect = rectf;
}

void Ellipse::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        QPointF pos = event->pos();
        m_pos = pos;

        if(m_pointUp.contains(pos))
        {
            m_up = true;
            setCursor(Qt::SizeVerCursor);
            event->accept();
            return ;
        }
        else if(m_pointLeft.contains(pos))
        {
            m_left = true;
            setCursor(Qt::SizeHorCursor);
            event->accept();
            return ;
        }
        else if(m_pointRight.contains(pos))
        {
            m_right = true;
            setCursor(Qt::SizeHorCursor);
            event->accept();
            return ;
        }
        else if(m_pointDown.contains(pos))
        {
            m_down = true;
            setCursor(Qt::SizeVerCursor);
            event->accept();
            return ;
        }
        m_isMoving = true;
    }
}

void Ellipse::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF newPos = event->pos();

    qreal dx = event->pos().x() - m_pos.x();
    qreal dy = event->pos().y() - m_pos.y();

    QRectF tmp = m_rect;
    QRectF last = tmp;

    bool flag = true;
    if(m_isMoving)
    {
        tmp.setRect(tmp.x()+dx, tmp.y()+dy, tmp.width(), tmp.height());
        QGraphicsItem::mouseMoveEvent(event);
    }
    else if(m_left)
    {
        tmp.setRect(tmp.x()+dx, tmp.y(), tmp.width()-dx, tmp.height());
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_down)
    {
        tmp.setRect(tmp.x(), tmp.y(), tmp.width(), tmp.height()+dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }
    else if(m_right)
    {
        tmp.setRect(tmp.x(), tmp.y(), tmp.width()+dx, tmp.height());
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_up)
    {
        tmp.setRect(tmp.x(), tmp.y()+dy, tmp.width(), tmp.height()-dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }

    // 小于某个值就退出
    if(tmp.width() <= 20)
    {
        m_rect = last;
        flag = false;
    }
    if(tmp.height() <= 30)
    {
        m_rect = last;
        flag = false;
    }
    if(flag)
    {
        m_pos = newPos;
        m_rect = tmp;
        m_SRect = QRectF(m_rect.topLeft() + QPointF(5, 5), m_rect.size()-QSize(10, 10));
    }
    prepareGeometryChange();
    scene()->update(boundingRect());
}

void Ellipse::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        if(m_isMoving || m_up || m_right || m_left || m_down)
        {
            m_isMoving = m_up = m_right = m_left = m_down = false;
            setCursor(Qt::OpenHandCursor);
            event->accept();
            emit upROIMask();
            return;
        }
        QGraphicsItem::mouseReleaseEvent(event);
    }
}

void Ellipse::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QPointF pos = event->pos();
    m_pos = pos;
    if(m_pointUp.contains(pos) || m_pointDown.contains(pos))
    {
        setCursor(Qt::SizeVerCursor);
        event->accept();
        return;
    }
    else if(m_pointLeft.contains(pos) || m_pointRight.contains(pos))
    {
        setCursor(Qt::SizeHorCursor);
        event->accept();
        return;
    }
    else
    {
        setCursor(Qt::OpenHandCursor);
        event->accept();
        return;
    }
}

// ------------------  Circle  ----------------------
Circle::Circle()
{
    m_shape = ROIShape::CIRCLE;
    m_rect.setRect(0, 0, m_rect.width(), m_rect.width());
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5,5), m_rect.size()-QSize(10,10));
}

Circle::Circle(QRectF &rectf)
{
    m_shape = ROIShape::CIRCLE;
    m_rect = rectf;
    m_SRect = QRectF(m_rect.topLeft()+QPointF(5,5), m_rect.size()-QSize(10,10));
}

void Circle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    QPointF newPos = event->pos();
    qreal dx = event->pos().x() - m_pos.x();
    qreal dy = event->pos().y() - m_pos.y();

    bool flag = true;
    QRectF tmp = m_rect;
    QRectF last = tmp;

    if(m_isMoving)
    {
        tmp.setRect(tmp.x()+dx, tmp.y()+dy, tmp.width(), tmp.height());
        QGraphicsItem::mouseMoveEvent(event);
    }
    else if(m_left)
    {
        tmp.setRect(tmp.x()+dx, tmp.y()+dx, tmp.width()-2*dx, tmp.width()-2*dx);
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_down)
    {
        tmp.setRect(tmp.x()-dy, tmp.y()-dy, tmp.height()+2*dy, tmp.height()+2*dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }
    else if(m_right)
    {
        tmp.setRect(tmp.x()-dx, tmp.y()-dx, tmp.width()+2*dx, tmp.width()+2*dx);
        setCursor(Qt::SizeHorCursor);
        event->accept();
    }
    else if(m_up)
    {
        tmp.setRect(tmp.x()+dy, tmp.y()+dy, tmp.width()-2*dy, tmp.height()-2*dy);
        setCursor(Qt::SizeVerCursor);
        event->accept();
    }

    // 小于某个值就退出
    if(tmp.width() <= 5)
    {
        m_rect = last;
        flag = false;
    }
    if(tmp.height() <= 5)
    {
        m_rect = last;
        flag = false;
    }
    if(flag)
    {
        m_pos = newPos;
        m_rect = tmp;
        m_SRect = QRectF(m_rect.topLeft() + QPointF(5, 5), m_rect.size()-QSize(10, 10));
    }
    prepareGeometryChange();
}

// ------------------  Polygon  ----------------------
Polygon::Polygon(const QPolygonF &polygon)
    :m_index(0)
{
    m_shape = ROIShape::POLYGON;
    m_polygon = polygon;
}

QRectF Polygon::boundingRect() const
{
    return shape().boundingRect();
}

void Polygon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    if(scene() == nullptr)
        return;
    scene()->update();

    QPen pen(Qt::red);
    pen.setStyle(Qt::DashLine);
    painter->setPen(pen);
    painter->drawPolygon(m_polygon);    // 画多边形

    // 画功能点
    if(m_isSelected)
    {
        for(auto pointf : m_polygon)
        {
            painter->setBrush(Qt::green);
            painter->drawRect(QRectF(pointf.x()-5, pointf.y()-5, 10, 10));
        }
    }
}

QPainterPath Polygon::shape() const
{
    QPainterPath path;
    path.addPolygon(m_polygon);
    return path;
}

void Polygon::setContextMenuEnabled(bool enable)
{
    m_contextMenuEnable = enable;
}

void Polygon::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        QPointF pos = event->pos();
        m_pos = pos;
        for (int i = 0; i < m_polygon.size(); ++i)
        {
            QRectF rect(m_polygon[i].x()-5, m_polygon[i].y()-5, 10, 10);
            if(rect.contains(pos))
            {
                m_index = i;
                m_isResizing = true;
                return ;
            }
        }
        m_isMoving = true;
    }
}

void Polygon::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    qreal dx = event->pos().x() - m_pos.x();
    qreal dy = event->pos().y() - m_pos.y();

    if(m_isMoving)
    {
        // qDebug() << "Polygon move";
        for(int i = 0; i < m_polygon.size(); ++i)
        {
            // QRectF rect(m_polygon[i].x()-5, m_polygon[i].y()-5, 10, 10);
            m_polygon[i] = QPointF(m_polygon[i].x()+dx, m_polygon[i].y()+dy);
        }
    }
    else if(m_isResizing)
    {
        m_polygon[m_index] = QPointF(m_pos.x()+dx, m_pos.y()+dy);
        setCursor(Qt::SizeAllCursor);
    }
    m_pos = event->pos();
    prepareGeometryChange();
}

void Polygon::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if(event->button() & Qt::LeftButton)
    {
        if(m_isMoving || m_isResizing)
        {
            m_isMoving = m_isResizing = false;
            setCursor(Qt::OpenHandCursor);
            event->accept();
            emit upROIMask();
            return ;
        }
        QGraphicsItem::mouseReleaseEvent(event);
    }
    else if(event->button() & Qt::RightButton)
    {
        setContextMenuEnabled(true);
    }
}

void Polygon::hoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    QPointF pos = event->pos();
    m_pos = pos;
    for(int i = 0; i < m_polygon.size(); ++i)
    {
        QRectF rect(m_polygon[i].x()-5, m_polygon[i].y()-5, 10, 10);
        if(rect.contains(pos))
        {
            setCursor(Qt::SizeAllCursor);
            return ;
        }
    }
    setCursor(Qt::OpenHandCursor);
}

void Polygon::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *del = new QAction("删除", this);
    menu.addAction(del);

    if(m_contextMenuEnable)
    {
        connect(del, &QAction::triggered, this, &Polygon::delROIItem);
        menu.exec(event->screenPos());
    }
    else
    {
        disconnect(del, &QAction::triggered, this, &Polygon::delROIItem);
    }
}

void Polygon::delROIItem(bool check)
{
    scene()->removeItem(this);
    emit upROIMask();
}
